package ar.com.sectorwine.controllers;

import java.security.Principal;
import java.util.List;
import java.util.Locale;
import java.util.Set;

import javax.validation.ConstraintViolation;
import javax.validation.Valid;
import javax.validation.Validator;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.servlet.ModelAndView;

import ar.com.sectorwine.dto.DetallesPublicacionesDTOMapper;
import ar.com.sectorwine.dto.EmpresaDTO;
import ar.com.sectorwine.dto.EmpresasDTOMapper;
import ar.com.sectorwine.dto.PublicacionDTO;
import ar.com.sectorwine.dto.PublicacionDTOMapper;
import ar.com.sectorwine.entities.Publicacion;
import ar.com.sectorwine.entities.Users;
import ar.com.sectorwine.repository.EmpresaRepository;
import ar.com.sectorwine.segimiento.DetallePublicacionDTO;
import ar.com.sectorwine.services.EmpresasService;
import ar.com.sectorwine.services.PublicacionesService;
import ar.com.sectorwine.services.UsuarioService;

@Controller
@Transactional(propagation = Propagation.REQUIRES_NEW)
public class PublicacionesController {
	@Autowired
	private EmpresasService empresasService;
	@Autowired
	private PublicacionesService publicacionesService;
	@Autowired
	private UsuarioService usuarioService;
	@Autowired
	private DetallesPublicacionesDTOMapper detallesPublicacionesDTOMapper;
	@Autowired
	PublicacionDTOMapper pubDTOMapper;
	@Autowired
	private Validator validator;

	@Autowired
	private EmpresasDTOMapper empresasDTOMapper;

	@Autowired
	EmpresaRepository empresaRepository;
	private static final Logger logger = LoggerFactory
			.getLogger(EmpresasController.class);

	@RequestMapping(value = "publicacion_modificar", method = RequestMethod.GET)
	public ModelAndView publicacion_modificar(Locale locale, Model model,
			Principal principal, @RequestParam Long idPublicacion) {
		Users usuarioActual = usuarioService.getUsuario(principal.getName());
		ModelAndView mav = new ModelAndView("publicaciones/publicacion_noticia");
		mav.addObject("mis_empresas", usuarioActual.getPerfilUsuario()
				.getEmpresas());
		mav.addObject("publicacion",
				publicacionesService.getPublicacionDTO(idPublicacion));
		return mav;
	}

	@RequestMapping(value = "publicacion_eliminar", method = RequestMethod.GET)
	public ModelAndView publicacion_eliminar(Locale locale, Model model,
			@RequestParam Long idPublicacion, @RequestParam String idEmpresa) {
		publicacionesService.eliminarPublicacion(idPublicacion);
		ModelAndView mav = new ModelAndView(
				"publicaciones/publicacion_noticias");
		mav.addObject("empresa", empresasService.getEmpresa(idEmpresa));
		return mav;
	}

	@RequestMapping(value = "/hay_actualizaciones", method = RequestMethod.GET)
	public @ResponseBody
	Boolean actualizar(@RequestParam("_") String cacheNumber,
			Principal principal) {
		logger.info("Se ejecuto actualizar");

		// return Sujeto.getInstancia().hayActualizaciones();

		return true;

	}

	@RequestMapping(value = "/get_actualizaciones", method = RequestMethod.GET)
	public @ResponseBody
	List<DetallePublicacionDTO> getDetallesPublicacion(Principal principal) {
		logger.info("Se ejecuto actualizar");

		return getDetallesPublicacion(principal, null);
	}

	@RequestMapping(value = "/get_actualizaciones_perfil", method = RequestMethod.GET)
	public @ResponseBody
	List<DetallePublicacionDTO> getDetallesPublicacion(Principal principal,
			@RequestParam String idEmpresa) {
		logger.info("Se ejecuto actualizar");
		List<Publicacion> publicaciones = publicacionesService
				.obtenerPublicaciones();

		Users usuarioActual = usuarioService.getUsuario(principal.getName());
		Long idEmpresaLong = null;

		if (idEmpresa != null) {
			idEmpresaLong = Long.getLong(idEmpresa);
		}

		return detallesPublicacionesDTOMapper.obtenerDetallesPublicacionesDTO(
				publicaciones, usuarioActual, idEmpresaLong);
	}

	// Publicacion
	// NOTICIA----------------------------------------------------------------------
	@RequestMapping(value = "publicacion", method = RequestMethod.GET)
	public ModelAndView publicacion_noticia1(@RequestParam("tipo") String tipo, Locale locale, Model model,
			Principal principal) {
		Users usuarioActual = usuarioService.getUsuario(principal.getName());

		if (!(usuarioActual.getPerfilUsuario().getEmpresas().isEmpty())) {

			List<EmpresaDTO> empresas = empresasDTOMapper
					.obtenerDTODesdeObjetoDelDominio(usuarioActual
							.getPerfilUsuario().getEmpresas());

			ModelAndView mav = new ModelAndView(
					"publicaciones/publicacion_noticia");
			mav.addObject("mis_empresas", empresas);
			mav.addObject("publicacion", new PublicacionDTO());
			
			mav.addObject("titulo", tipo);

			return mav;
		} else {
			ModelAndView mav = new ModelAndView("empresas/empresas_alta");
			mav.addObject("empresa", new EmpresaDTO());
			mav.addObject("mensajeCabecera",
					"Aun no tienes una empresa creada. Crea un perfil para ella!");
			logger.info("El usuario " + usuarioActual.getUsername()
					+ " no tiene empresa creada.");
			return mav;
		}
	}

	@RequestMapping(value = "noticias_publicar", method = RequestMethod.POST)
	public ModelAndView publicar(@Valid @ModelAttribute("publicacion") PublicacionDTO publicacionDTO,
			BindingResult result, SessionStatus status, Principal principal) {

		Set<ConstraintViolation<PublicacionDTO>> failures = validator
				.validate(publicacionDTO);
		Users usuarioActual = usuarioService.getUsuario(principal.getName());
		List<EmpresaDTO> empresas = empresasDTOMapper
				.obtenerDTODesdeObjetoDelDominio(usuarioActual
						.getPerfilUsuario().getEmpresas());
		if (failures.size() == 0) {

			publicacionesService.crearPublicacion(
					empresaRepository.findOne(publicacionDTO.getIdEmpresa()),
					usuarioService.getUsuario(principal.getName()), 3/*
																	 * 3 =
																	 * Noticia
																	 */,
					publicacionDTO.getCuerpo(), publicacionDTO.getTitulo(),
					publicacionDTO.getImagen(),
					publicacionDTO.getBreveDescripcion(), null,
					publicacionDTO.getFuente(), publicacionDTO.getTag_split());
			ModelAndView mav = new ModelAndView("empresas/empresas_perfil");
			mav.addObject("empresa",
					empresaRepository.findOne(publicacionDTO.getIdEmpresa()));
			return mav;
		} else {
			ModelAndView mav = new ModelAndView(
					"publicaciones/publicacion_noticia");
			mav.addObject("publicacion", publicacionDTO);
			mav.addObject("empresa",
					empresaRepository.findOne(publicacionDTO.getIdEmpresa()));
			mav.addObject("mis_empresas", empresas);
			return mav;
		}
	}

	@RequestMapping(value = "noticias_republicar", method = RequestMethod.GET)
	public ModelAndView republicacion_noticia1(Locale locale, Model model,
			Principal principal, @RequestParam String idPublicacion) {

		PublicacionDTO pub = publicacionesService.getPublicacionDTO(Long
				.parseLong(idPublicacion));
		pub.setIdEmpresa(null);
		Users usuarioActual = usuarioService.getUsuario(principal.getName());
		if (!(usuarioActual.getPerfilUsuario().getEmpresas().isEmpty())) {
			ModelAndView mav = new ModelAndView(
					"publicaciones/republicacion_noticia");
			mav.addObject("mis_empresas", usuarioActual.getPerfilUsuario()
					.getEmpresas());
			mav.addObject("publicacion", pub);

			return mav;
		} else {
			ModelAndView mav = new ModelAndView("empresas/empresas_alta");
			mav.addObject("empresa", new EmpresaDTO());
			mav.addObject("mensajeCabecera",
					"Aun no tienes una empresa creada. Crea un perfil para ella!");
			logger.info("El usuario " + usuarioActual.getUsername()
					+ " no tiene empresa creada.");
			return mav;
		}
	}

	@RequestMapping(value = "noticias_republicar", method = RequestMethod.POST)
	public ModelAndView republicar(
			Locale locale,
			Model model,
			@Valid @ModelAttribute("publicacion") PublicacionDTO publicacionDTO,
			Principal principal) {
		if (publicacionDTO.getIdPublicacionFuente() == null) {
			publicacionDTO.setIdPublicacionFuente(publicacionDTO.getId());
		}
		publicacionesService.crearPublicacion(
				empresaRepository.findOne(publicacionDTO.getIdEmpresa()),
				usuarioService.getUsuario(principal.getName()),
				3/* 3 = Noticia */, publicacionDTO.getCuerpo(),
				publicacionDTO.getTitulo(), publicacionDTO.getImagen(),
				publicacionDTO.getBreveDescripcion(), null,
				publicacionDTO.getFuente(), publicacionDTO.getTag_split(),
				publicacionDTO.getIdEmpresaFuente(),
				publicacionDTO.getIdPublicacionFuente());
		ModelAndView mav = new ModelAndView("empresas/empresas_perfil");
		mav.addObject("empresa",
				empresaRepository.findOne(publicacionDTO.getIdEmpresa()));
		return mav;
	}

	@RequestMapping(value = "publicacion_noticia", method = RequestMethod.POST)
	public ModelAndView publicacion_noticia(Locale locale, Model model,
			@RequestParam String id) {
		ModelAndView mav = new ModelAndView(
				"publicaciones/publicacion_noticias");
		mav.addObject("empresa", empresasService.getEmpresa(id));
		return mav;
	}

	// Publicacion
	// ENLACE----------------------------------------------------------------------
	@RequestMapping(value = "publicacion_enlace", method = RequestMethod.GET)
	public ModelAndView publicacion_enlace(Locale locale, Model model,
			Principal principal) {
		Users usuarioActual = usuarioService.getUsuario(principal.getName());
		if (!(usuarioActual.getPerfilUsuario().getEmpresas().isEmpty())) {
			ModelAndView mav = new ModelAndView(
					"publicaciones/publicacion_enlace");
			mav.addObject("mis_empresas", usuarioActual.getPerfilUsuario()
					.getEmpresas());
			mav.addObject("publicacion", new PublicacionDTO());
			return mav;
		} else {
			ModelAndView mav = new ModelAndView("empresas/empresas_alta");
			mav.addObject("empresa", new EmpresaDTO());
			mav.addObject("mensajeCabecera",
					"Aun no tienes una empresa creada. Crea un perfil para ella!");
			logger.info("El usuario " + usuarioActual.getUsername()
					+ " no tiene empresa creada.");
			return mav;
		}
	}

	// Publicacion
	// ESTADO----------------------------------------------------------------------
	@RequestMapping(value = "publicacion_estado", method = RequestMethod.GET)
	public ModelAndView publicacion_estado(Locale locale, Model model,
			Principal principal) {
		Users usuarioActual = usuarioService.getUsuario(principal.getName());
		if (!(usuarioActual.getPerfilUsuario().getEmpresas().isEmpty())) {
			ModelAndView mav = new ModelAndView(
					"publicaciones/publicacion_estado");

			List<EmpresaDTO> empresas = empresasDTOMapper
					.obtenerDTODesdeObjetoDelDominio(usuarioActual
							.getPerfilUsuario().getEmpresas());

			mav.addObject("mis_empresas", empresas);
			mav.addObject("publicacion", new PublicacionDTO());
			return mav;
		} else {
			ModelAndView mav = new ModelAndView("empresas/empresas_alta");
			mav.addObject("empresa", new EmpresaDTO());
			mav.addObject("mensajeCabecera",
					"Aun no tienes una empresa creada. Crea un perfil para ella!");
			logger.info("El usuario " + usuarioActual.getUsername()
					+ " no tiene empresa creada.");
			return mav;
		}
	}

	@RequestMapping(value = "estado_publicar", method = RequestMethod.POST)
	public ModelAndView publicarEstado(@Valid @ModelAttribute("publicacion") PublicacionDTO publicacionDTO,
			BindingResult result, SessionStatus status, Principal principal) {
		Set<ConstraintViolation<PublicacionDTO>> failures = validator
				.validate(publicacionDTO);
		Users usuarioActual = usuarioService.getUsuario(principal.getName());
		
		List<EmpresaDTO> empresas = empresasDTOMapper
				.obtenerDTODesdeObjetoDelDominio(usuarioActual
						.getPerfilUsuario().getEmpresas());

		if (failures.size() == 0) {
			publicacionDTO.setUsuarioCreador(usuarioActual);
			publicacionesService
					.crearPublicacion(empresaRepository.findOne(publicacionDTO
							.getIdEmpresa()), usuarioService
							.getUsuario(principal.getName()), pubDTOMapper
							.obtenerObjetoDelDominioDesdeDTO(publicacionDTO), 4/* Estado */);

			ModelAndView mav = new ModelAndView("empresas/empresas_perfil");
			mav.addObject("empresa",
					empresaRepository.findOne(publicacionDTO.getIdEmpresa()));
			return mav;
		} else {
			ModelAndView mav = new ModelAndView(
					"publicaciones/publicacion_estado");
			mav.addObject("publicacion", publicacionDTO);

			mav.addObject("mis_empresas", empresas);
			return mav;
		}
	}

	// Publicacion
	// VIDEO----------------------------------------------------------------------
	@RequestMapping(value = "publicacion_video", method = RequestMethod.GET)
	public ModelAndView publicacion_video(Locale locale, Model model,
			Principal principal) {
		Users usuarioActual = usuarioService.getUsuario(principal.getName());
		if (!(usuarioActual.getPerfilUsuario().getEmpresas().isEmpty())) {
			ModelAndView mav = new ModelAndView(
					"publicaciones/publicacion_video");
			mav.addObject("mis_empresas", usuarioActual.getPerfilUsuario()
					.getEmpresas());
			mav.addObject("publicacion", new PublicacionDTO());
			return mav;
		} else {
			ModelAndView mav = new ModelAndView("empresas/empresas_alta");
			mav.addObject("empresa", new EmpresaDTO());
			mav.addObject("mensajeCabecera",
					"Aun no tienes una empresa creada. Crea un perfil para ella!");
			logger.info("El usuario " + usuarioActual.getUsername()
					+ " no tiene empresa creada.");
			return mav;
		}
	}

	@RequestMapping(value = "video_publicar", method = RequestMethod.POST)
	public ModelAndView publicarVideo(
			Locale locale,
			Model model,
			@Valid @ModelAttribute("publicacion") PublicacionDTO publicacionDTO,
			Principal principal) {
		publicacionesService.crearPublicacion(
				empresaRepository.findOne(publicacionDTO.getIdEmpresa()),
				usuarioService.getUsuario(principal.getName()),
				5/* 5 = Video */, null, null, null,
				publicacionDTO.getBreveDescripcion(), publicacionDTO.getUrl(),
				publicacionDTO.getFuente(), publicacionDTO.getTag());
		ModelAndView mav = new ModelAndView("empresas/empresas_perfil");
		mav.addObject("empresa",
				empresaRepository.findOne(publicacionDTO.getIdEmpresa()));
		return mav;
	}

	// Publicacion
	// IMAGEN----------------------------------------------------------------------
	@RequestMapping(value = "publicacion_imagen", method = RequestMethod.GET)
	public ModelAndView publicacion_imagen(Locale locale, Model model,
			Principal principal) {
		Users usuarioActual = usuarioService.getUsuario(principal.getName());
		if (!(usuarioActual.getPerfilUsuario().getEmpresas().isEmpty())) {
			ModelAndView mav = new ModelAndView(
					"publicaciones/publicacion_imagen");
			mav.addObject("mis_empresas", usuarioActual.getPerfilUsuario()
					.getEmpresas());
			mav.addObject("publicacion", new PublicacionDTO());
			return mav;
		} else {
			ModelAndView mav = new ModelAndView("empresas/empresas_alta");
			mav.addObject("empresa", new EmpresaDTO());
			mav.addObject("mensajeCabecera",
					"Aun no tienes una empresa creada. Crea un perfil para ella!");
			logger.info("El usuario " + usuarioActual.getUsername()
					+ " no tiene empresa creada.");
			return mav;
		}
	}

	@RequestMapping(value = "imagen_publicar", method = RequestMethod.POST)
	public ModelAndView publicarImagen(
			Locale locale,
			Model model,
			@Valid @ModelAttribute("publicacion") PublicacionDTO publicacionDTO,
			Principal principal) {

		PublicacionDTOMapper pubDTOMapper = new PublicacionDTOMapper();
		publicacionesService
				.crearPublicacion(empresaRepository.findOne(publicacionDTO
						.getIdEmpresa()), usuarioService.getUsuario(principal
						.getName()), pubDTOMapper
						.obtenerObjetoDelDominioDesdeDTO(publicacionDTO), 5/* Imagen */);

		// publicacionesService.crearPublicacion(
		// empresaRepository.findOne(publicacionDTO.getIdEmpresa()),
		// usuarioService.getUsuario(principal.getName()),
		// 5/* 2 = Imagen */, null, null, null,
		// publicacionDTO.getBreveDescripcion(), publicacionDTO.getUrl(),
		// publicacionDTO.getFuente(), publicacionDTO.getTag());
		ModelAndView mav = new ModelAndView("empresas/empresas_perfil");
		mav.addObject("empresa",
				empresaRepository.findOne(publicacionDTO.getIdEmpresa()));
		return mav;
	}

	@RequestMapping(value = "republicacion_noticia", method = RequestMethod.GET)
	public ModelAndView publicacion_republicar(Locale locale, Model model,
			Principal principal, @RequestParam Long idPublicacion) {
		Users usuarioActual = usuarioService.getUsuario(principal.getName());
		ModelAndView mav = new ModelAndView(
				"publicaciones/republicacion_noticia");
		mav.addObject("mis_empresas", usuarioActual.getPerfilUsuario()
				.getEmpresas());
		mav.addObject("publicacion",
				publicacionesService.getPublicacionDTO(idPublicacion));
		return mav;
	}
}
